package zack.project.domain.award.service.distribute.impl;

import zack.project.domain.award.adapter.repository.IAwardRepository;
import zack.project.domain.award.model.aggregate.GiveOutPrizesAggregate;
import zack.project.domain.award.model.entity.DistributeAwardEntity;
import zack.project.domain.award.model.entity.UserAwardRecordEntity;
import zack.project.domain.award.model.entity.UserCreditAwardEntity;
import zack.project.domain.award.model.valobj.AwardStateVO;
import zack.project.domain.award.service.distribute.IDistributeAward;
import zack.project.types.common.Constants;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.MathContext;

/**积分奖品的发奖节点
 * @author A1793
 */
@Component("user_credit_random")
public class UserCreditRandomAward implements IDistributeAward {

    @Resource
    private IAwardRepository awardRepository;

    @Override
    public void giveOutPrize(DistributeAwardEntity distributeAward) {
        //获得奖品配置
        String awardConfig = distributeAward.getAwardConfig();
        Integer awardId = distributeAward.getAwardId();

        if( StringUtils.isBlank(awardConfig)) {
            awardConfig = awardRepository.queryAwardConfig(awardId);
        }

        String[] split = awardConfig.split(Constants.SPLIT);

        if(split.length != 2) {
            throw new RuntimeException("award_config 「" + awardConfig + "」配置不是一个范围值，如 1,100");
        }
        //获取配置的积分范围之间的一个随机值
        BigDecimal creditAmount =  generateRandom(new BigDecimal(split[0]),new BigDecimal(split[1]));
        //构建用户积分奖品实体
        UserCreditAwardEntity userCreditAwardEntity = GiveOutPrizesAggregate.
                buildUserCreditAwardEntity(distributeAward.getUserId(), creditAmount);
        //根据奖品id和抽奖单id构建用户中奖记录实体，
        // 该中奖记录在数据库表{user_raffle_award}中存在，本次操作要将该记录的状态改为completed
        UserAwardRecordEntity userAwardRecordEntity = GiveOutPrizesAggregate.
                buildUserAwardRecordEntity(distributeAward.getUserId(), distributeAward.getOrderId(), distributeAward.getAwardId(), AwardStateVO.complete);

        GiveOutPrizesAggregate giveOutPrizesAggregate = new GiveOutPrizesAggregate();
        giveOutPrizesAggregate.setUserCreditAwardEntity(userCreditAwardEntity);
        giveOutPrizesAggregate.setUserAwardRecord(userAwardRecordEntity);
        giveOutPrizesAggregate.setUserId(distributeAward.getUserId());
        //
        awardRepository.saveGiveOutPrizesAggregate(giveOutPrizesAggregate);
    }

    private BigDecimal generateRandom(BigDecimal min, BigDecimal max) {
        if (min.equals(max)) {
            return min;
        }
        BigDecimal randomBigDecimal = min.add(BigDecimal.valueOf(Math.random()).multiply(max.subtract(min)));
        return randomBigDecimal.round(new MathContext(3));
    }
}
